﻿/*****************************************************
**Copyright(C), 2021-2022, Ciqtek Technology.
**Version:     1.0
**Author:      dingyy
**Date:        2021/12/15
**Description: 自定义代理
*****************************************************/

#ifndef CUSTOMESTYLEDDELEGATE_H
#define CUSTOMESTYLEDDELEGATE_H

#include "../generalui_global.h"
#include "../GlobalUIDef.h"

#include <QStyledItemDelegate>

#define ID_COMBOBOX_ITEMLIST  Qt::UserRole + 100

namespace GeneralUI {

	/**
	 * @brief  只读代理
	 */
	class GENERALUI_EXPORT ReadOnlyDelegate : public QStyledItemDelegate
	{
		Q_OBJECT

	public:
		/**
		 * @brief  ReadOnlyDelegate 默认构造函数
		 * @param  parent
		 * @return
		 */
		ReadOnlyDelegate(QObject *parent = 0);

		/**
		 * @brief  ~ReadOnlyDelegate 默认析构函数
		 * @return
		 */
		~ReadOnlyDelegate();

	public:
		/**
		 * @brief  createEditor 第一步：创建一个Widget作为编辑器
		 * @param  parent
		 * @param  option
		 * @param  index
		 * @return QT_NAMESPACE::QWidget*
		 */
		QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
	};

	/**
	 * @brief  整形/浮点输入框代理
	 */
	class GENERALUI_EXPORT CreateSpinBoxDelegate : public QStyledItemDelegate
	{
		Q_OBJECT

	public:
		/**
		 * @brief  输入框代理类型
		 */
		enum SpinBoxDelegateType
		{
			TYPE_SPINBOX = 0,           ///< 整数
			TYPE_DBSPINBOX              ///< 浮点数
		};

	public:
		/**
		 * @brief  CreateSpinBoxDelegate 默认构造函数
		 * @param  parent
		 * @return
		 */
		explicit CreateSpinBoxDelegate(QObject *parent = nullptr, SpinBoxDelegateType type = TYPE_DBSPINBOX, double minValue = -99999.0, double maxValue = 99999.0);

		/**
		 * @brief  ~CreateSpinBoxDelegate 默认析构函数
		 * @return
		 */
		~CreateSpinBoxDelegate();

	public:
		/**
		 * @brief  setDecimals  浮点数输入框精度
		 * @param  decimals  精度
		 * @return void
		 * @note  浮点数代理时有效
		 */
		void setDecimals(int decimals);

		/**
		 * @brief  setCommitDataImmediately  设置是否在修改中更新Model数据
		 * @param  commitDataImmediately
		 * @return void
		 */
		inline void setCommitDataImmediately(bool commitDataImmediately) { m_commitDataImmediately = commitDataImmediately; };

	public:
		/**
		 * @brief  createEditor 第一步：创建一个Widget作为编辑器
		 * @param  parent
		 * @param  option
		 * @param  index
		 * @return QT_NAMESPACE::QWidget*
		 */
		QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;

		/**
		 * @brief  updateEditorGeometry 第二步：编辑器的显示位置
		 * @param  editor
		 * @param  option
		 * @param  index
		 * @return void
		 */
		void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

		/**
		 * @brief  setEditorData 第三步：初始化显示数据
		 * @param  editor
		 * @param  index
		 * @return void
		 */
		void setEditorData(QWidget *editor, const QModelIndex &index) const;

		/**
		 * @brief  setModelData 第四步：用户完成编辑、编辑器被关闭时，提供数据到model
		 * @param  editor
		 * @param  model
		 * @param  index
		 * @return void
		 */
		void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;

		/**
		 * @brief  paint 绘制
		 * @param  painter
		 * @param  option
		 * @param  index
		 * @return void
		 */
		void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

	private Q_SLOTS:
		/**
		 * @brief  commitDataFunc  更新数据
		 * @param  *
		 * @return void
		 */
		void commitDataFunc();

	private:
		/**  代理类型
		 */
		SpinBoxDelegateType m_delegateType;

		/**  最大值
		 */
		double m_maxValue;

		/**  最小值
		 */
		double m_minValue;

		/**  浮点数输入框精度
		 */
		int m_decimals;

		/** 是否在修改过程中更新Model数据
		 */
		bool m_commitDataImmediately;
	};

	/**
	 * @brief  下拉菜单代理
	 */
	class GENERALUI_EXPORT CreateComboBoxDelegate : public QStyledItemDelegate
	{
		Q_OBJECT

	public:
		/**
		 * @brief  CreateSpinBoxDelegate 默认构造函数
		 * @param  parent
		 * @return
		 */
		explicit CreateComboBoxDelegate(QObject *parent = nullptr);

		/**
		 * @brief  ~CreateSpinBoxDelegate 默认析构函数
		 * @return
		 */
		~CreateComboBoxDelegate();

	public:
		/**
		 * @brief  createEditor 第一步：创建一个Widget作为编辑器
		 * @param  parent
		 * @param  option
		 * @param  index
		 * @return QT_NAMESPACE::QWidget*
		 */
		QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;

		/**
		 * @brief  updateEditorGeometry 第二步：编辑器的显示位置
		 * @param  editor
		 * @param  option
		 * @param  index
		 * @return void
		 */
		void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

		/**
		 * @brief  setEditorData 第三步：初始化显示数据
		 * @param  editor
		 * @param  index
		 * @return void
		 */
		void setEditorData(QWidget *editor, const QModelIndex &index) const;

		/**
		 * @brief  setModelData 第四步：用户完成编辑、编辑器被关闭时，提供数据到model
		 * @param  editor
		 * @param  model
		 * @param  index
		 * @return void
		 */
		void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;

		/**
		 * @brief  paint 绘制
		 * @param  painter
		 * @param  option
		 * @param  index
		 * @return void
		 */
		void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

	};

}//namespace OfUI

#endif // CUSTOMESTYLEDDELEGATE_H